home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 050 / turbodos.arc / TURBORUN.ASM < prev    next >
Assembly Source File  |  1985-12-13  |  21KB  |  451 lines

  1.  
  2. Page 60,132
  3. Title TURBORUN a utility for Turbo Pascal, MS/PC-DOS v2.xx
  4. Name TurboRun
  5.  
  6. ;************************************************************************
  7. ;*                                                                      *
  8. ;*                            T U R B O R U N                           *
  9. ;*                              Version 1.2                             *
  10. ;*                                                                      *
  11. ;*                 By John Cooper       John Falconer                   *
  12. ;*                    (913) 262-8451    (415) 521-7245                  *
  13. ;*                    CIS  74775,756    CIS  72435,1617                 *
  14. ;*                                                                      *
  15. ;*                       Update to Version 1.2 by                       *
  16. ;*                                                                      *
  17. ;*                               Tom Devitt                             *
  18. ;*                           Pseudonym Software                         *
  19. ;*                             (818) 796-7933                           *
  20. ;*                                                                      *
  21. ;************************************************************************
  22.  
  23. Comment*
  24.  
  25. Revision History
  26.         Version 1.0 was successfully tested on 12/10/84.
  27.                    By John Cooper
  28.  
  29.         Updated to Version 1.0A on 12/22/84.
  30.                    By John Falconer
  31.  
  32.             1.  Changed ssmax from a constant to a code-base-relative
  33.                 value.  This change allows Turborun to be used with
  34.                 different versions of Turbo Pascal.  Although undocumented,
  35.                 the four versions of Turbo I tested all store their
  36.                 maximum stack segment size as a word located seven bytes
  37.                 ahead of the beginning of user code.
  38.             2.  Added code to determine the length of the command line
  39.                 which is passed to the child process.  Moved the child's
  40.                 command line starting point to PSP+081H as called for in
  41.                 the DOS manual (Ver 2.0 page E-6) and placed the length
  42.                 byte for the command line at PSP+080H.  This allows the
  43.                 command line passed to the child to be used as a string
  44.                 with string[0] containing the valid length.  Note that
  45.                 a carriage return is placed at the end of the passed command
  46.                 line but that it is not counted in the length.  Note also
  47.                 that this change corrupts the CmdLine variable passed
  48.                 to Turborun by changing the last character of the file
  49.                 name to the length of the child's CmdLine.
  50.             3.  Changed original code so that all characters on the command
  51.                 line are passed on to the child.  This is as called for in
  52.                 the DOS manual.  Previously the first terminator (usually
  53.                 a space) was skipped over.
  54.             4.  Corrected a few minor documentation errors.
  55.  
  56. Note:           The EXEC call does not support IO-Redirection on the command
  57.                 line.
  58. *
  59. Page
  60. Comment *
  61.  
  62.         Updated to Version 1.0B January 10, 1985
  63.                    By John Cooper
  64.  
  65.             1.  A note concerning the lack of IO-redirection support
  66.                 by the MS/PC DOS EXEC function call, the call which is
  67.                 at the heart of this program, was ammended, as it has
  68.                 been determined that, at least in the case of MS-DOS 2.11,
  69.                 EXEC does provide full IO-redirection, via the command line
  70.                 symbols "> < |", if the command processor is envolked ahead
  71.                 of the child.
  72.  
  73.                 <Child> [FCB-1 [FCB-2]] >PIPEOUT <PIPEIN
  74.  
  75.                 The above will NOT work, however,
  76.  
  77. [path][drive]COMMAND.COM /C <Child> [FCB-1 [FCB-2]] >PIPEOUT <PIPEIN
  78.  
  79.                 should work just fine.
  80.  
  81.  
  82.             2.  Changed the way in which the program detects the end
  83.                 of the childs name, to include all filename separators,
  84.                 as listed on page 1-88 of MS-DOS v2.0 Programmer's
  85.                 Reference, except the back-slash (\) and colon (:).  These
  86.                 two were excluded because the program needs to accept a
  87.                 full-path name, which could include these symbols.  Pre-
  88.                 viously only a space or null was considered a terminator.
  89.                 This change was recommended but not implemented in version
  90.                 1.0A.
  91.  
  92.             3.  Added notes on installation concerning the requirement,
  93.                 introduced by an enhancement made in 1.0A, that the
  94.                 external declaration of this program be the first in the
  95.                 Turbo source code.  Also added some warnings and documentation
  96.                 notes.
  97. *
  98. Page
  99. Comment *
  100.  
  101.         Updated to Version 1.1 March 17, 1985
  102.                 By John Falconer
  103.  
  104.             1.  A "bug" in the way memory allocation is calculated and
  105.                 set to protect Turbo's SSEG was fixed.  The program is now
  106.                 known to function with such large applications as 1-2-3 and
  107.                 Dbase III.
  108.  
  109.         Updated to Version 1.2 on April 28, 1985
  110.                 By Tom Devitt
  111.  
  112.             1.  Made Version 1.2 compatible with the 2.0 AND 3.0 versions
  113.                 of Turbo Pascal by modifying the method in which ssmax
  114.                 is located.  Under 3.0 TP stores the maximum stack segment
  115.                 size 20 bytes ahead of the beginning of user code.  However,
  116.                 both versions store this value at CS:[101H] + 112H. This
  117.                 change should make the placement of the EXTERNAL RUN proc
  118.                 unimportant.
  119.  
  120.             2.  Acknowledgement:  I owe a debt to the guys at Pathfinder
  121.                 Software Inc., publishers of TurboLink.  Although TL 2.0
  122.                 contains a bug which makes it unusable on > 512k systems,
  123.                 I was able to discover the above fact by analysing their
  124.                 code.
  125.  
  126.             3.  With Turbo Pascal 2.0B, you must first compile in memory
  127.                 and only then switch over to the com option, limiting
  128.                 memory before the second compile.  With Turbo Pascal
  129.                 3.0B, you may skip the memory compile.
  130. *
  131. Page
  132. Comment*
  133.  
  134.                          - - - W A R N I N G - - -
  135.         Although every effort has been made, by the two authors, to
  136.         ensure that this program will perform as specified, there are
  137.         may be programs which will not function correctly when envoked
  138.         from Turbo, via Turborun, but will do just fine if envoked
  139.         from COMMAND.COM.  An excellent example is WordStar(tm).  In
  140.         some, but not all, cases this can be solved by first envoking
  141.         COMMAND.COM and then envoking the child from COMMAND.COM.
  142.         Assume that there is a program, WORKING.COM, that will not
  143.         work from Turborun but does work from DOS.  The following
  144.         command line might help;
  145.  
  146.          COMMAND.COM /c WORKING.COM
  147.  
  148.         This of course assume that there is not a shortage of
  149.         memory of some other explainable problem.  The switch, /c,
  150.         is included to force COMMAND.COM to return control to the
  151.         parent after the processing of its, COMMAND.COM's, command line.
  152.  
  153.  
  154. Installation Notes:
  155.         The enhancement to provide for a version-independent SSMAX,
  156.         provided by John F., has introduced the additional requirement
  157.         that this external be the first code generating structute in
  158.         the Turbo Pascal source code, i.e. make TurboRun the first
  159.         procedure, following the Const, Type, and Var blocks, in the
  160.         main program.  Turborun assumes it is the first and can,
  161.         therefore, find the SSMAX word exactly seven bytes prior to
  162.         its own base address.
  163.  
  164.         Note: Under Version 1.2, the above requirement may be relaxed.
  165.         - TD
  166.  
  167.         Memory Compiles.
  168.                 The use of this program in "memory mode" is not recom-
  169.                 mended.  Turbo seems to dislike having its memory
  170.                 limited, which is required to run the child.  It may
  171.                 work but it is, at best, risky!  The prefered method
  172.                 is to do a memory-compile, if possible, then switch to
  173.                 Com and limit the Maximum Stack Size and compile again,
  174.                 this time producing a COM file.  If compilation to memory
  175.                 is not possible, due to lack of memory or the use of
  176.                 Overlays, you MUST implement some sort of patch to
  177.                 work around Turbo Pascal 2.0B's known "bug" in its handling
  178.                 of externals greater that 128-bytes in length.  The "bug"
  179.                 is easy to work around, by either loading the external
  180.                 at run-time(recommended) or converting it to an INLINE
  181.                 $Include file.
  182.  
  183.                 Note: Above bug appears to have been fixed in Turbo
  184.                 Pascal 3.0B - TD
  185.  
  186. *
  187. Page
  188. Comment *
  189.  
  190.         Limiting the Stack Segment for Turbo Pascal.
  191.                 If the Stack Size is not limited, at compile-time, then
  192.                 Turbo Pascal may want to consume all of the system's
  193.                 available RAM.  Of course, that precludes the use of child
  194.                 processes because the BLOCK call will fail, due to a lack
  195.                 of resources.   It is, therefore, recommended that you limit
  196.                 Maximum Stack Size to just enough memory to allow the Pascal
  197.                 program to operate, this will leave the balance of your
  198.                 system's resources available for child processes.
  199.  
  200.  
  201.         Terminate But Stay Resident.
  202.                 Programs which use "Terminate but stay resident" or
  203.                 "Keep process" to terminate but keep itself in memory should
  204.                 not be run from Turborun.  The reason is that will cause
  205.                 DOS to attempt to set the allocation block map to prevent
  206.                 overlaying of the child.  If the system survives this, it
  207.                 still leave DOS in an unpredictable state.
  208.  
  209.  
  210.         Exit codes.
  211.                 In order for the parent to correctly detect the reason the
  212.                 child terminated the child must pass that infomation back,
  213.                 so that the Get Return Code can find it.  Many currently,
  214.                 available programs do not provide this and hence the code
  215.                 value passed back to RetCode may not reflect the actual
  216.                 reason the child was terminated.  An example is COMMAND.COM.
  217.  
  218.         "BUGS".
  219.                 If you encounter difficulties using this program or you find
  220.                 "bugs" in it, please contact either author or the latest
  221.                 revisor.
  222.  
  223.  
  224.         After this source code is assembled, linked, and converted to
  225.         a COM file it should be included as an external procedure
  226.         within the Turbo Pascal source file.  The external should be
  227.         of the form shown below.
  228.  
  229.         Procedure GoForIt(Var RetCode:Integer; Var Cmdline);
  230.                 External 'TurboRun.com';
  231.  
  232.         Cmdline can be either type-CHAR or type-STRING.  If the latter
  233.         is used you should pass CmdLine[1] to skip the length byte.
  234.  
  235.         Format of CmdLine:
  236. path-name-to-child [<sp> First-FCB [<sp> Second-FCB [<sp> switchs and/or IO redirection]]] #0
  237.  
  238.         Notice that the Cmdline to followed by a byte of 0, this is binary 0
  239.         not ASCII 0. <-- VERY IMPORTANT!
  240.  
  241. *
  242. Page
  243. Comment *
  244.  
  245.         The variable, RetCode, will contain the return code from the
  246.         child process.  RetCode is actually used as two, seperate,
  247.         byte-length variables.  The table below explains how to interpret
  248.         this variable in terms of its high and low bytes.
  249.  
  250.         High byte
  251.                 0 : Normal Termination, No error
  252.                 1 : Child was terminated via by CONTROL-C
  253.                 2 : Child was aborted because of a DOS Hard Error
  254.                 3 : Child used terminate-but-stay-resident
  255.                     (System needs to be rebooted)
  256.                 4 : EXEC call failed.
  257.                 8 : Memory allocation error, EXEC was not attempted
  258.  
  259.         In the cases of 0,1,2, and 3 the low byte has the value passed
  260.         back by the child.  Any of these values indicate that the EXEC
  261.         call was successful.  Programs which use terminate-but-stay-
  262.         resident should not be called by the program.
  263.  
  264.         In the case of 4 the low byte has the reason the EXEC failed.
  265.           2 : The path specified was invalid or not found.
  266.           8 : There was not enough memory for the process to be created.
  267.          11 : The process was an EXE format file and contained information
  268.               that was internally inconsistent.
  269.  
  270.         In the case of 8 the low byte has the reason the memory allocation
  271.         request failed.
  272.           7 : The arena was trashed because a user program has changed
  273.               memory that does not belong to it. System needs to be Rebooted.
  274.           8 : Insufficient memory.
  275.  
  276. *
  277. Page
  278. Subttl Main Program
  279. ;
  280. ;------------------- E Q U A T E S --------------------
  281. ;
  282. spsave  equ     cs:00fch        ;Storage for SP register
  283. sssave  equ     cs:00feh        ;Storage for SS register
  284. ;
  285. ;-------------------- M A C R O S ---------------------
  286. ;
  287. MsDos   Macro   function
  288.         If function lt 256
  289.         mov     ah,function
  290.         Else
  291.         mov     ax,function
  292.         EndIf
  293.         int     21h
  294.         EndM
  295. ;
  296. ;
  297. ;------------------ M A I N  P R O G R A M -----------------
  298. ;
  299. code            segment para public 'CODE'
  300.                 assume  cs:code,ds:nothing,es:code,ss:nothing
  301.  
  302.                 org 00h
  303. run             proc    near
  304.                 call    entry   ;Find out where we were loaded
  305.                                 ;There is no return from this CALL
  306. separate        db     ';,=+"[]><| ',9,0 ;Filename separators
  307.                                 ;Excluding ":" and "\" which cannot appear in
  308.                                 ;a filename but can appear in a pathname.
  309.  
  310. child           db      128 dup(?)      ;Path to child (with filename extension)
  311. fcb1            db      16 dup(?)       ;Optional fcb
  312. fcb2            db      16 dup(?)       ;Optional fcb
  313. parablk         dw      0,12 dup(?)     ;Parameter block (DOS 2.0 Manual p. D-45)
  314. cmdstrt         dw      0               ;Offset to first char in child's CmdLine
  315. ssmax           dw      0               ;Storage for parent's maximum stack size,
  316.                                         ;in paragraphs
  317.  
  318. entry:          pop     bx              ;Offset+3
  319.                 sub     bx,3            ;Actual offset address of RUN.COM
  320.                 pop     dx              ;Turbo(tm) return address
  321.                 pop     si              ;Offset to command string
  322.                 pop     cx              ;Segment address of command string
  323.                 push    dx              ;Restore turbo's RET address
  324.                 mov     dx,si
  325.                 push    ds
  326.                 push    bp
  327.                 pushf
  328.  
  329.                 push    bx              ;Save bx temporarily
  330.                 mov     ax,112h         ;Offest of ssmax
  331.                 mov     bx,CS:[101H]    ;pointer to user code
  332.                 add     bx,ax           ;bx = addr ssmax
  333.                 mov     ax,cs:[bx]      ;Move it to ax
  334.                 pop     bx              ;Recover bx
  335.                 mov     [ssmax+bx],ax   ;Save the max stack size for SETBLOCK call
  336.  
  337.                 mov     ds,cx           ;Point to command string segment
  338.                 push    cs              ;Make ES=CS
  339.                 pop     es
  340.                 mov     di,offset child ;Child process path name
  341.                 add     di,bx           ;Relocation offset
  342.                 cld                     ;Force direction
  343. cmdlp:          lodsb                   ;Get character
  344.                 push    di              ;Save DI
  345.                 mov     cx,13           ;look for any of 13 filename separators
  346.                 mov     di,offset separate
  347.                 add     di,bx           ;Relocation offset
  348.                 repnz   scasb           ;Look for match
  349.                 jz      endstr          ;Exit if a separator is found
  350.                 pop     di              ;Otherwise, retrieve DI and continue
  351.                 stosb                   ;Store byte
  352.                 jmp     cmdlp           ;Try next character
  353. endstr:         pop     di              ;Retrieve DI
  354.                 mov     [cmdstrt+bx],si ;Pointer to first char in child's CmdLine
  355.                 mov     al,0            ;Put terminating 0 in child path
  356.                 stosb
  357.                 dec     si              ;Back up one for stosb
  358.                 dec     si              ;Back up one for the length byte
  359.  
  360. ;ds:si point to the childs command line
  361.  
  362. u1:             mov     [parablk+2+bx],si ;Store offset address
  363.                 inc     si              ;Start parsing at head of child's CmdLine
  364.                 mov     cx,ds
  365.                 mov     [parablk+4+bx],cx ;Store segment address
  366.                 mov     di,offset fcb1  ;Setup to parse first filename
  367.                 add     di,bx           ;Relocation
  368.  
  369. ;di has offset from cs to default FCB passed at 5Ch
  370.  
  371.                 mov     [parablk+6+bx],di
  372.                 MsDos   2901h           ;Ignore leading separators
  373.                 mov     di,offset fcb2  ;Parse second filename
  374.                 add     di,bx           ;Relocation
  375.  
  376. ;di has offset from cs to default FCB passed at 6Ch
  377.  
  378.                 mov     [parablk+10+bx],di
  379.                 MsDos   2901h
  380. ;
  381. ;Place <cr> at end of CmdLine, calculate and store child's CmdLine length
  382. ;
  383. u2:             cmp     byte ptr ds:[si],0 ;Look for end of line
  384.                 jz      u3
  385.                 inc     si
  386.                 jmp     u2
  387. u3:             mov     byte ptr ds:[si],13
  388.  
  389.                 mov     ax,[cmdstrt+bx] ;Get pointer to first char in child's CmdLine
  390.                 xchg    ax,si           ;Swap it with current pointer
  391.                 dec     si              ;We don't include the <cr> in our length
  392.                 sub     ax,si           ;Calculate the length
  393.                 dec     si              ;Point to the length byte
  394.                 mov     byte ptr ds:[si],al ;Store calculated length there
  395.  
  396.                 mov     cx,cs           ;Setup segments in parameter block
  397.                 mov     [parablk+8+bx],cx
  398.                 mov     [parablk+12+bx],cx
  399.                 mov     [parablk+bx],0  ;Pass environment to child, unchanged
  400.  
  401. ;Now the childs parameter block is setup.
  402. ;All that remains is to allocate memory and go for it.
  403.  
  404.                 push    bx              ;Save reloc register
  405.                 mov     bx,[ssmax+bx]
  406.                 push    cx
  407.                 mov     cx,ss
  408.                 add     bx,cx
  409.                 pop     cx
  410.                 sub     bx,cx
  411.                 MsDos   4ah             ;Modify memory allocation
  412.                 jnc     $+5
  413.                 jmp     alocer          ;Allocation error, Exit
  414.                 pop     bx              ;Recover reloc register
  415.                 push    bx              ;Save a copy on stack
  416.                 mov     dx,bx
  417.                 add     bx,offset parablk
  418.                 mov     [spsave],sp     ;Save SP
  419.                 mov     [sssave],ss     ;Save SS
  420.                 push    cs              ;Point ds:sx to child
  421.                 pop     ds
  422.                 add     dx,offset child
  423.                 MsDos   4b00h           ;Go for it
  424.                 cli                     ;Prevent interuption
  425.                 mov     sp,[spsave]     ;Recover SP
  426.                 mov     ss,[sssave]     ;Recover SS
  427.                 sti
  428.                 jnc     $+5
  429.                 jmp     runerr          ;Problems, Exit
  430.                 pop     bx              ;Get reloc register
  431.                 MsDos   4dh             ;Get return code from child
  432. getbac:         popf                    ;Turbo's Flags
  433.                 pop     bp              ;Turbo's BP
  434.                 pop     ds              ;Turbo's DS
  435.                 pop     cx              ;Return address
  436.                 pop     di              ;Offset to RC Variable
  437.                 pop     es              ;Segment of RC Variable
  438.                 mov     es:[di],ax      ;Store return code
  439.                 push    cx              ;Restore return address
  440.                 ret                     ;Back to Turbo
  441.  
  442. alocer:         pop     bx              ;Reloc register
  443.                 mov     ah,8            ;Indicate Allocation error
  444.                 jmp     getbac
  445. runerr:         pop     bx
  446.                 mov     ah,4            ;Indicate RUN error
  447.                 jmp     getbac
  448. run             endp
  449. code            ends
  450.                 end     run
  451.